﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace SurfaceInteraction.UI.Surface.Helper
{
    public static class Extensions
    {
        public static byte[] GetImage(this UIElement source, double scale, int quality, List<Point> subCoords, double orientation, Point center)
        {
            double actualHeight = source.RenderSize.Height;
            double actualWidth = source.RenderSize.Width;

            double renderHeight = actualHeight * scale;
            double renderWidth = actualWidth * scale;

            RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)renderWidth, (int)renderHeight, 96, 96, PixelFormats.Pbgra32);
            VisualBrush sourceBrush = new VisualBrush(source);

            DrawingVisual drawingVisual = new DrawingVisual();
            DrawingContext drawingContext = drawingVisual.RenderOpen();

            using (drawingContext)
            {
                drawingContext.PushTransform(new ScaleTransform(scale, scale));
                drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), new Point(actualWidth, actualHeight)));
            }

            renderTarget.Render(drawingVisual);

            int targetWidth = 240;
            int targetHeight = 400;

            // rotate the master image around the point
            RotateTransform rotateTransform = new RotateTransform();
            rotateTransform.CenterX = center.X;
            rotateTransform.CenterY = center.Y;
            rotateTransform.Angle = orientation * -1;

            // move the point up to the top left
            TranslateTransform translateTransform = new TranslateTransform();
            translateTransform.X = (-1 * (center.X - 240 / 2));
            translateTransform.Y = (-1 * (center.Y - 400 / 2));

            TransformGroup transformGroup = new TransformGroup();
            transformGroup.Children.Add(rotateTransform);
            transformGroup.Children.Add(translateTransform);

            // create an image element to do all the manipulation. This is a cheap way of
            // getting around doing the math myself.
            Image image = new Image();
            image.Stretch = Stretch.None;
            image.Source = renderTarget;
            image.RenderTransform = transformGroup;

            // more ui cruft. This is just for layout
            Canvas container = new Canvas();
            container.Children.Add(image);
            container.Arrange(new Rect(0, 0, renderTarget.PixelWidth, renderTarget.PixelHeight));

            // render the result to a new bitmap. 
            RenderTargetBitmap target = new RenderTargetBitmap(targetWidth, targetHeight, 96, 96, PixelFormats.Default);
            target.Render(container);

            byte[] imageArray;
            using (MemoryStream stream = new MemoryStream())
            {
                var encoder = new JpegBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(target));
                encoder.Save(stream);
                imageArray = stream.ToArray();
            }

            return imageArray;
        }

        public static Point GetRotatedPoint(this Point original, double angle, double width, double height)
        {
            double x = (width / 2) * Math.Cos(angle) + (height / 2) * Math.Sin(angle) + original.X;
            double y = -(width / 2) * Math.Sin(angle) - (height / 2) * Math.Cos(angle) + original.Y;
            return new Point(x, y);
        }
    }
}
